package org.jeecg.modules.doctor;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import java.io.IOException;
import com.google.common.collect.Lists;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import org.apache.commons.lang3.StringUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.modules.doctor.entity.Doctor;
import org.jeecg.common.modules.doctor.entity.DoctorAssistantRelation;
import org.jeecg.common.modules.doctor.entity.DoctorPatientRelation;
import org.jeecg.common.modules.doctor.service.*;
import org.jeecg.common.modules.group.entity.GroupId;
import org.jeecg.common.modules.group.service.IGroupIdService;
import org.jeecg.common.modules.im.ImService;
import org.jeecg.common.modules.patient.entity.Patient;
import org.jeecg.common.modules.patient.service.IPatientService;
import org.jeecg.common.modules.wx.entity.WxUserinfo;
import org.jeecg.common.modules.wx.service.IWxUserinfoService;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.util.ImageUrl;
import org.jeecg.common.util.enums.BusinessTypeEnum;
import org.jeecg.common.util.enums.SexEnum;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.common.modules.doctor.entity.DoctorWxUserinfoRelation;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;

import org.jeecg.common.util.tencent.request.CreateGroupRequest;
import org.jeecg.common.util.tencent.request.MemberRequest;
import org.jeecg.common.util.tencent.response.IMBaseResponse;
import org.jeecg.common.util.wx.WxUrlConvert;
import org.jeecgframework.poi.excel.ExcelImportUtil;
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.jeecgframework.poi.excel.entity.ImportParams;
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
import org.jeecg.common.system.base.controller.JeecgController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;
import com.alibaba.fastjson.JSON;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.weixin4j.WeixinConfig;

import org.jeecg.config.CustomProperties;
import org.weixin4j.spring.WeixinTemplate;

/**
 * @Description: doctor_wx_userinfo_relation
 * @Author: jeecg-boot
 * @Date:   2020-10-29
 * @Version: V1.0
 */
@Api(tags="doctor_wx_userinfo_relation")
@RestController
@RequestMapping("/dwuRelation/dwuRelation")
@Slf4j
public class DoctorWxUserinfoRelationController extends JeecgController<DoctorWxUserinfoRelation, IDoctorWxUserinfoRelationService> {
	@Resource
	private IDoctorService doctorService;
	@Resource
	private IWxUserinfoService wxUserinfoService;
	@Resource
	private IPatientService patientService;
	@Resource
	private IDoctorPatientRelationService doctorPatientRelationService;
	@Resource
	private IDoctorWxUserinfoRelationService doctorWxUserinfoRelationService;
	@Resource
	private ImService imService;
	@Resource
	private IDoctorAssistantRelationService doctorAssistantRelationService;
	@Resource
	private IDoctorConfigService doctorConfigService;
	@Resource
	private IGroupIdService groupIdService;
	@Resource
	private WeixinTemplate weixinTemplate;
	@Resource
	private CustomProperties customProperties;
	/**
	 * 分页列表查询
	 *
	 * @param doctorWxUserinfoRelation
	 * @param pageNo
	 * @param pageSize
	 * @param req
	 * @return
	 */
	@AutoLog(value = "doctor_wx_userinfo_relation-分页列表查询")
	@ApiOperation(value="doctor_wx_userinfo_relation-分页列表查询", notes="doctor_wx_userinfo_relation-分页列表查询")
	@GetMapping(value = "/list")
	public Result<?> queryPageList(DoctorWxUserinfoRelation doctorWxUserinfoRelation,
								   @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
								   @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
								   HttpServletRequest req) {
		QueryWrapper<DoctorWxUserinfoRelation> queryWrapper = QueryGenerator.initQueryWrapper(doctorWxUserinfoRelation, req.getParameterMap());
		Page<DoctorWxUserinfoRelation> page = new Page<DoctorWxUserinfoRelation>(pageNo, pageSize);
		IPage<DoctorWxUserinfoRelation> pageList = doctorWxUserinfoRelationService.page(page, queryWrapper);
		return Result.ok(pageList);
	}


	 /**
	  * 医生和用户关系中聊天室的创立
	  *
	  * 聊天室的创立涉及到的表：
	  * doctor_wx_userinfo_relation
	  * doctor_patient_relation
	  * group_id
	  */
	 @GetMapping(value = "/doctorUser")
//	 public Result<?> doctorUser(@RequestParam(name="doctorId",required=true) String doctorId,
//								 @RequestParam(name="userInfoId",required=true) String userInfoId) {
	 public Result<?> doctorUser(@RequestParam(name="num",required=true) String nums) {
	     int num = Integer.valueOf(nums);
	 	 int size  = 100;
	 	 int start = 10000 + ((num - 1) * size) + 1;
	 	 int end   = 10000 + num * size;

	 	 List<DoctorWxUserinfoRelation> doctorWxUserinfoRelations = doctorWxUserinfoRelationService.getLimitInfo(start,end);
		 log.info("\n\n+++++++++++++++医生用户关系数据+++++++++++++++\n"+doctorWxUserinfoRelations+"\n++++++++++++++++++++++++++++++");
	 	 for(DoctorWxUserinfoRelation doctorWxUserinfoRelation:doctorWxUserinfoRelations){
	 	 	 WxUserinfo wxUserinfo = wxUserinfoService.getByOpenid(doctorWxUserinfoRelation.getOpenid());
			 log.info("\n\n+++++++++++++++用户数据+++++++++++++++\n"+wxUserinfo+"\n++++++++++++++++++++++++++++++");
			 boolean chatResult = this.chatRoom(doctorWxUserinfoRelation.getDoctorId(),wxUserinfo.getId());
			 if(!chatResult){
			 	continue;
			 }
		 }

//		 this.chatRoom(doctorId,userInfoId);
		 return Result.ok("执行成功");
	 }

	/**
	 * 根据关系id创建聊天室
	 * @return
	 */
	 @GetMapping(value = "/imCreate")
	 public Result<?> imCreate(@RequestParam(name="id",required=true) String id) {
	 	 //获取关系信息
		 DoctorWxUserinfoRelation relation = doctorWxUserinfoRelationService.getById(id);

		 String doctorId     = relation.getDoctorId();
		 WxUserinfo wxUserinfo = wxUserinfoService.getByOpenid(relation.getOpenid());
		 String wxUserInfoId = wxUserinfo.getId();
		 this.chatRoom(doctorId,wxUserInfoId);
		 return Result.ok("执行成功");
	 }

	 private boolean chatRoom(String doctorId,String userInfoId){
		 Doctor doctor = doctorService.getById(doctorId);                      //当前医生信息
		 WxUserinfo wxUserinfo = wxUserinfoService.getById(userInfoId);        //当前患者对应的用户信息
		 Patient patient = patientService.getSelfByWxUserinfoId(userInfoId);   //当前患者信息
		 log.info("\n\n+++++++++++++++医生数据+++++++++++++++\n"+doctor+"\n++++++++++++++++++++++++++++++");
		 log.info("\n\n+++++++++++++++用户数据+++++++++++++++\n"+wxUserinfo+"\n++++++++++++++++++++++++++++++");
		 log.info("\n\n+++++++++++++++患者数据+++++++++++++++\n"+patient+"\n++++++++++++++++++++++++++++++");

		 if (Objects.nonNull(doctor)){
			 //【一】初始化医患关系：（医患关系新增 / 医患关系查询）
			 doctorPatientRelationService.initRelation(doctorId,patient.getId());

			 //【二】获取医生和用户关系的信息（医生的名字默认为医生）
			 DoctorWxUserinfoRelation wxUserinfoRelation = doctorWxUserinfoRelationService.getByDoctorAndOpenid(doctorId,wxUserinfo.getOpenid());
			 //医生用户关系不存在=》添加信息（除IM_id外）【针对数据库】
			 if (Objects.isNull(wxUserinfoRelation)){
				 wxUserinfoRelation = doctorWxUserinfoRelationService.initRelation(doctorId,wxUserinfo.getOpenid(),null);
			 }

			 log.info("\n\n+++++++++++++++医生用户关系数据+++++++++++++++\n"+wxUserinfoRelation+"\n++++++++++++++++++++++++++++++");

			 String str = "200";
			 //【三】IM group_id 不存在=》进行创建
			 if (StringUtils.isBlank(wxUserinfoRelation.getImGroupId())){
//			 if (wxUserinfoRelation.getImGroupId() == null && wxUserinfoRelation.getImGroupId().length() == 0){
				 log.info("\n\n\n++++++++++++++IM正在创建聊天室++++++++++++++++++++\n");
			 	 //创建聊天室id
//				 Integer groupIdNow = this.createGroupId(wxUserinfo);
//
//				 //患者对应的用户信息导入im账户
//				 IMBaseResponse importUserRes = imService.importAccount(wxUserinfo.getId(),wxUserinfo.getNickname(),wxUserinfo.getHeadimgurl());
//				 if(!importUserRes.getActionStatus().equals("OK")){
//					 this.imImportRes(importUserRes,groupIdNow);
//					 return false;
//				 }
//
//				 //医生对应的信息导入im账户
//				 IMBaseResponse importDoctorRes = imService.importAccount(doctor.getId(),BusinessTypeEnum.DOCTOR.getDesc(), ImageUrl.handle(doctor.getHeadImg()));
//				 if(!importDoctorRes.getActionStatus().equals("OK")){
//					 this.imImportRes(importDoctorRes,groupIdNow);
//					 return false;
//				 }
//
//				 //组织最终的群内成员信息组
//				 CreateGroupRequest request = buildGroupRequest(wxUserinfo,doctor,groupIdNow);
//				 IMBaseResponse createRes = imService.createGroup(request);
//
//				 //更新创建的结果
//				 this.imImportRes(createRes,groupIdNow);
//
//				 if(createRes.getActionStatus().equals("OK")){  //创建成功
//					 //更改医生用户关系表的im_groupId字段【针对数据库】
//					 wxUserinfoRelation.setImGroupId(request.getGroupId());
//					 doctorWxUserinfoRelationService.updateById(wxUserinfoRelation);
//				 }else{
//					 return false;
//				 }
			 }else{
				 log.info("\n\n\n++++++++++++++IM没有创建聊天室++++++++++++++++++++\n");
			 }

		 }
		 return true;
	 }

	/**
	 * 创建聊天室id
	 * @param wxUserinfo
	 * @return
	 */
	private int createGroupId(WxUserinfo wxUserinfo){
		 //group_id 表数据进行添加：获得group_id
		 GroupId groupId = new GroupId();
		 groupId.setName(wxUserinfo.getNickname());
		 groupIdService.save(groupId);
		 return groupId.getId();
	 }

	/**
	 * 聊天室id表存储结果
	 */
	private void imImportRes(IMBaseResponse importRes,Integer id){
		GroupId groupId = groupIdService.getById(id);
		if(importRes.getActionStatus().equals("OK")){  //创建成功
			groupId.setStatus(1);
		}else{
			groupId.setStatus(importRes.getErrorCode());
			groupId.setError(importRes.getErrorInfo());
		}
		//保存结果
		groupIdService.updateById(groupId);
	}

	/*
      创建请求数据
     */
	private static final String FACE_URL_TEMPLATE = "%s/r/%s";
	private CreateGroupRequest buildGroupRequest(WxUserinfo patient,Doctor doctor,Integer groupId){
		CreateGroupRequest request = new CreateGroupRequest();
		request.setGroupId(String.valueOf(groupId));            //创建腾讯IM的类
		request.setName(getGroupName(patient));                 //聊天室id
		if (StringUtils.isNotBlank(patient.getHeadimgurl())){   //聊天室名称
			request.setFaceUrl(String.format(FACE_URL_TEMPLATE,customProperties.getH5Domain(),patient.getId()));  //群组头像
		}

		//获得所有的助理，添加到IM信息组中,去请求腾讯
		List<DoctorAssistantRelation> allReleations = doctorAssistantRelationService.queryByDoctorId(doctor.getId());  //医生名下的所有医生助理关系
		List<Doctor> doctors = allReleations.stream().map(item -> doctorService.getById(item.getAssistantId())).collect(Collectors.toList()); //医生名下所有助理的信息集合
		doctors.add(doctor);  //（医生助理和医生信息）组织成一个集合

		List<MemberRequest> members = doctors.stream().map(item -> buildMemberRequest(item,doctor.getId())).collect(Collectors.toList());//医生+助理信息处理到一个集合
		members.add(buildMemberRequest(patient));//患者信息追加到刚刚（医生+助理）的集合中

		request.setOwnerAccount(doctor.getId());  //设置群主
		request.setMemberList(members);
		return request;
	}

	/*
	  组织当前用户的数据
	 */
	private MemberRequest buildMemberRequest(WxUserinfo wxUserinfo){
		MemberRequest request = new MemberRequest();
		request.setMemberAccount(wxUserinfo.getId());
		MemberRequest.MemberDefineData memberDefineData = new MemberRequest.MemberDefineData();
		memberDefineData.setKey("business");
		memberDefineData.setValue(BusinessTypeEnum.PATIENT.getId().toString());
		request.setAppMemberDefinedData(Lists.newArrayList(memberDefineData));
		return request;
	}

	/*
      组织当前医生的数据
     */
	private MemberRequest buildMemberRequest(Doctor doctor,String doctorId){
		MemberRequest request = new MemberRequest();
		request.setMemberAccount(doctor.getId());
		MemberRequest.MemberDefineData memberDefineData = new MemberRequest.MemberDefineData();
		memberDefineData.setKey("business");
		memberDefineData.setValue(doctor.getBusinessType().toString());
//        if (!StringUtils.equals(doctorId,doctor.getId())){
//            request.setRole(GroupMemberRole.ADMIN.getRole());
//        }
		request.setAppMemberDefinedData(Lists.newArrayList(memberDefineData));
		return request;
	}

	/*
	  设置群组名称
	  */
	private String getGroupName(WxUserinfo wxUserinfo){
		StringBuffer sb = new StringBuffer();
		if (StringUtils.isNotBlank(wxUserinfo.getNickname())){
			String name = this.subGroupName(wxUserinfo.getNickname());
			sb.append(name);
		}
		if (Objects.nonNull(wxUserinfo.getSex())){
			sb.append("  ");
			sb.append(SexEnum.getInstance(wxUserinfo.getSex()).getDesc());
		}
		if (StringUtils.isBlank(sb.toString())){
			sb.append(wxUserinfo.getId());
		}
		return sb.toString();
	}

	/*
	 * 按字节截取字符串
	 */
//	@GetMapping(value = "/groupName")
	public String subGroupName(String name){
		if(this.getByteLength(name) <= 24){
			return name;
		}else{
			int cutBytes = 20;
			if(name == null || "".equals(name.trim())) {
				return "";
			}

			int lastIndex = 0;
			boolean stopFlag = false;

			int totalBytes = 0;
			for(int i=0; i<name.length(); i++) {
				String s = Integer.toBinaryString(name.charAt(i));
				if(s.length() > 8) {
					totalBytes += 3;
				} else {
					totalBytes += 1;
				}

				if(!stopFlag) {
					if(totalBytes == cutBytes) {
						lastIndex = i;
						stopFlag = true;
					} else if(totalBytes > cutBytes) {
						lastIndex = i - 1;
						stopFlag = true;
					}
				}
			}

			if(!stopFlag) {
				return name+"...";
			} else {
				return name.substring(0, lastIndex + 1)+"...";
			}
		}
	}

	/**
	 * 获取字符串的字节数
	 * @param name
	 * @return
	 */
	public static int getByteLength(String name) {
		byte[] buff = name.getBytes();
		return buff.length;
	}












	 /**
	 *   添加
	 *
	 * @param doctorWxUserinfoRelation
	 * @return
	 */
	@AutoLog(value = "doctor_wx_userinfo_relation-添加")
	@ApiOperation(value="doctor_wx_userinfo_relation-添加", notes="doctor_wx_userinfo_relation-添加")
	@PostMapping(value = "/add")
	public Result<?> add(@RequestBody DoctorWxUserinfoRelation doctorWxUserinfoRelation) {
		doctorWxUserinfoRelationService.save(doctorWxUserinfoRelation);
		return Result.ok("添加成功！");
	}
	
	/**
	 *  编辑
	 *
	 * @param doctorWxUserinfoRelation
	 * @return
	 */
	@AutoLog(value = "doctor_wx_userinfo_relation-编辑")
	@ApiOperation(value="doctor_wx_userinfo_relation-编辑", notes="doctor_wx_userinfo_relation-编辑")
	@PutMapping(value = "/edit")
	public Result<?> edit(@RequestBody DoctorWxUserinfoRelation doctorWxUserinfoRelation) {
		doctorWxUserinfoRelationService.updateById(doctorWxUserinfoRelation);
		return Result.ok("编辑成功!");
	}
	
	/**
	 *   通过id删除
	 *
	 * @param id
	 * @return
	 */
	@AutoLog(value = "doctor_wx_userinfo_relation-通过id删除")
	@ApiOperation(value="doctor_wx_userinfo_relation-通过id删除", notes="doctor_wx_userinfo_relation-通过id删除")
	@DeleteMapping(value = "/delete")
	public Result<?> delete(@RequestParam(name="id",required=true) String id) {
		doctorWxUserinfoRelationService.removeById(id);
		return Result.ok("删除成功!");
	}
	
	/**
	 *  批量删除
	 *
	 * @param ids
	 * @return
	 */
	@AutoLog(value = "doctor_wx_userinfo_relation-批量删除")
	@ApiOperation(value="doctor_wx_userinfo_relation-批量删除", notes="doctor_wx_userinfo_relation-批量删除")
	@DeleteMapping(value = "/deleteBatch")
	public Result<?> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
		this.doctorWxUserinfoRelationService.removeByIds(Arrays.asList(ids.split(",")));
		return Result.ok("批量删除成功!");
	}
	
	/**
	 * 通过id查询
	 *
	 * @param id
	 * @return
	 */
	@AutoLog(value = "doctor_wx_userinfo_relation-通过id查询")
	@ApiOperation(value="doctor_wx_userinfo_relation-通过id查询", notes="doctor_wx_userinfo_relation-通过id查询")
	@GetMapping(value = "/queryById")
	public Result<?> queryById(@RequestParam(name="id",required=true) String id) {
		DoctorWxUserinfoRelation doctorWxUserinfoRelation = doctorWxUserinfoRelationService.getById(id);
		if(doctorWxUserinfoRelation==null) {
			return Result.error("未找到对应数据");
		}
		return Result.ok(doctorWxUserinfoRelation);
	}

    /**
    * 导出excel
    *
    * @param request
    * @param doctorWxUserinfoRelation
    */
    @RequestMapping(value = "/exportXls")
    public ModelAndView exportXls(HttpServletRequest request, DoctorWxUserinfoRelation doctorWxUserinfoRelation) {
        return super.exportXls(request, doctorWxUserinfoRelation, DoctorWxUserinfoRelation.class, "doctor_wx_userinfo_relation");
    }

    /**
      * 通过excel导入数据
    *
    * @param request
    * @param response
    * @return
    */
    @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
        return super.importExcel(request, response, DoctorWxUserinfoRelation.class);
    }

}
